#include <mysql/mysqld_error.h>
#include <signal.h>

void db_reconnect(NNFW_DB *db)
{
	if (g_exiting) {
		db_close(db);
		return;
	}
	mysql_init(&db->mysql);
	for(int i=0; i<6; i++)
	{
		MYSQL *p = mysql_real_connect(&db->mysql, g_sql_host, g_sql_username, g_sql_password, g_sql_database, g_sql_port, 0, 0);
		if(p) break;
		printf("[SQL ERROR] %d, %s\n", i, mysql_error(&db->mysql));
		sleep(10);
		mysql_close(&db->mysql);
		mysql_init(&db->mysql);
	}
}

NNFW_DB *db_connect()
{
	NNFW_DB *db = new NNFW_DB;
	db_reconnect(db);
	return db;
}

void db_close(NNFW_DB *db)
{
	if (db) {
		mysql_close(&db->mysql);
		delete db;
	}
	db = NULL;
}

char *db_clean_string(NNFW_DB *db, char *string)
{
	char *c = string;
	size_t i, len = strlen(string) & 0x1FF;
	for (i = 0; i < len; i++) {
		bool isdigit = (c[i] >= '0' && c[i] <= '9');
		bool isalpha = (c[i] >= 'a' && c[i] <= 'z') || (c[i] >= 'A' && c[i] <= 'Z');
		bool issepch = (c[i] == '=' || c[i] == ',' || c[i] == ';' || c[i] == '.');
		bool isextra = (c[i] == '/' || c[i] == '-' || c[i] == '_');
		if (!isdigit && !isalpha && !issepch && !isextra) { c[i] = '\0'; break; }
	}
	return string;
}

static void clean_html(char* string)
{
	char *c = string;
	size_t i, len = strlen(string) & 0x1FF;
	for (i = 0; i < len; i++) {
		if (c[i] == '<' || c[i] == '>' || c[i] == '%' || c[i] == '\\' || c[i] == '"' || c[i] == '\'') {
			c[i] = '\0'; break;
		}
	}
	if (strstr(string, "script")) strcpy(string, "");
}

void db_query(NNFW_DB *db, const char *format, ...)
{
	va_list arglist;
	va_start(arglist, format);
	if(!db) return;
	char *buffer = (char *)malloc(YAAMP_SMALLBUFSIZE+strlen(format));
	if(!buffer) return;
	int len = vsprintf(buffer, format, arglist);
	va_end(arglist);

	while(!g_exiting)
	{
		int res = mysql_query(&db->mysql, buffer);
		if(!res) break;
		res = mysql_errno(&db->mysql);
		printf("[SQL ERROR] %d, %s\n", res, mysql_error(&db->mysql));
		if(res == ER_DUP_ENTRY) break; 		// rarely seen on new user creation
		if(res != CR_SERVER_GONE_ERROR && res != CR_SERVER_LOST) exit(1);
		usleep(100 * 1000);					//100毫秒
		db_reconnect(db);
	}

	free(buffer);
}
